package edu.wpi.cs509.ui;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.image.BufferedImage;
import java.util.Timer;
import java.util.TimerTask;

import javax.swing.BorderFactory;
import javax.swing.JPanel;
import javax.swing.border.Border;

import edu.wpi.cs509.representation.PlayerPiece;
import edu.wpi.cs509.ui.images.StrategoPieceImage;


@SuppressWarnings("serial")
public class GameBoardSquare extends JPanel {

	private static final int BORDER = 4;
	private int row, col;
	private PlayerPiece piece = null;
	
	private GameBoardPanel board;
	private JPanel imagePanel;
    
    private MouseAdapter mouseAdapter;
    
    private Border highlightBorder = BorderFactory.createLineBorder(Color.ORANGE,BORDER);
    private Border emptyBorder = BorderFactory.createEmptyBorder(BORDER,BORDER,BORDER,BORDER);
    
    public GameBoardSquare(int row, int col, final GameBoardPanel board,GameBoardNotify event) {
 
    	this.row = row;
    	this.col = col;
    	this.board = board;

    	mouseAdapter = new InitGameAdapter(board,this,event);
    	addMouseListener(mouseAdapter);
        
    	// set the preferred size
    	
    	int length = Math.max(StrategoPieceImage.MARSHALL.getWidth(), StrategoPieceImage.MARSHALL.getHeight());
    	
    	int width = length + (2 * BORDER);
    	int height = length + (2 * BORDER);
    	
    	//setBorder(BorderFactory.createLineBorder( Color.WHITE, BORDER ));
    	
    	setLayout( new BorderLayout() );
    	setBorder( emptyBorder );
    	
    	imagePanel = new JPanel();
    	imagePanel.setPreferredSize( StrategoPieceImage.MARSHALL.getSize() );
    	imagePanel.setVisible(true);
    	
    	add( imagePanel, BorderLayout.CENTER );
    	
        setPreferredSize(new Dimension(width,height));
        
        setVisible(true);
        
    }

    public void paintComponent(Graphics g) {

    	Dimension dim = this.getSize();
    	
    	dim.width -= (2*BORDER);
    	if (dim.width < 0) dim.width = 0;
    	
    	dim.height -= (2*BORDER);
    	if (dim.height < 0) dim.height = 0;
    	
    	if (piece != null) {
        	StrategoPieceImage pieceImage = StrategoPieceImage.get( piece.getPieceType() );
        	BufferedImage img = pieceImage.getScaledImage(piece.getColor(), dim);
        	
        	// locate upper left corner
        	// (square width - left border - right border - image width) / 2
        	int xOffset = (getSize().width - BORDER - BORDER - img.getWidth()) / 2;
        	g.drawImage(img, BORDER+xOffset, BORDER, null);
        }

    }

    public void addPiece( PlayerPiece piece ) {
    	this.piece = piece;
    	repaint();
    }

    public void removePiece() {
    	this.piece = null;
    	board.repaint();
    }

	public int getCol() {
		return col;
	}

	public int getRow() {
		return row;
	}
	
	private boolean selected = false;
	public void select() {
		selected = true;
		setBorder(highlightBorder);
		repaint();
	}
	public void deselect() {
		selected = false;
		setBorder(emptyBorder);
		board.repaint();
	}
	public boolean isSelected() {
		return selected;
	}
	public void changeMouseAdapter(GameBoardNotify event) {
		this.removeMouseListener(mouseAdapter);
		// TODO this needs to be uncommented once MidGameAdapter is implemented correctly
		mouseAdapter = new MidGameAdapter(board, this, event);
    	addMouseListener(mouseAdapter);
    	
	}

	/** 
	 * Blinks the border on the square for timeout msec
	 * @param msec
	 */
	public void blink( int count ) {
		return;
		//Timer timer = new Timer();
		//timer.schedule(new BlinkGameBoardSquare(timer,count), 0, 100);
	}
	
	class BlinkGameBoardSquare extends TimerTask {

		private int count;
		private Timer timer;
		
		public BlinkGameBoardSquare(Timer timer, int count) {
			this.count = count;
			this.timer = timer;
			setBorder(highlightBorder);
		}
		
		@Override
		public void run() {
			if (getBorder() == highlightBorder) {
				setBorder(emptyBorder);
			} else {
				setBorder(highlightBorder);
			}
			
			count--;
			
			if (count <= 0) {
				timer.cancel();
				setBorder(emptyBorder);
				repaint();
			}
		}
		
	}
}
